package org.slg.oracleproject.config;

import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.enums.SecuritySchemeType;
import io.swagger.v3.oas.annotations.info.Contact;
import io.swagger.v3.oas.annotations.info.Info;
import io.swagger.v3.oas.annotations.security.SecurityScheme;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.parameters.Parameter;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import org.slg.oracleproject.util.QueryWlanAddressUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springdoc.core.customizers.OperationCustomizer;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.method.HandlerMethod;

import java.util.Arrays;
import java.util.List;

/**
 * Swagger配置：API文档信息+全局Authorization参数
 */
@Configuration
@OpenAPIDefinition(
        info = @Info(
                title = "测试项目",
                description = "测试项目接口文档",
                version = "1.0",
                contact = @Contact(
                        name = "沙龙果",
                        email = "1478699371@qq.com",
                        url = "${server.ip}/doc.html"
                )
        )
)
@SecurityScheme(
        name = "bearerAuth",
        type = SecuritySchemeType.HTTP,
        scheme = "bearer",
        bearerFormat = "JWT"
)
public class SwaggerConfig {

    @Value("${server.ip:${springdoc.api-docs.server-url:http://localhost:8080}}")
    private String serverIp;

    // 排除不需要Token的接口
    private static final List<String> EXCLUDE_PATHS = Arrays.asList("/auth/login", "/auth/refresh-token");

    /**
     * 全局添加Authorization请求头（排除登录接口）
     */
    @Bean
    public OperationCustomizer globalOperationCustomizer() {
        return (Operation operation, HandlerMethod handlerMethod) -> {
            String requestPath = getRequestPath(handlerMethod);
            if (requestPath == null || EXCLUDE_PATHS.contains(requestPath)) {
                return operation;
            }

            // 添加Token参数
            Parameter authorizationHeader = new Parameter()
                    .name("Authorization")
                    .description("Token（无需Bearer前缀）")
                    .in("header")
                    .required(true);
            operation.addParametersItem(authorizationHeader);
            return operation;
        };
    }

    // 获取接口完整路径
    private String getRequestPath(HandlerMethod handlerMethod) {
        RequestMapping classMapping = handlerMethod.getBeanType().getAnnotation(RequestMapping.class);
        RequestMapping methodMapping = handlerMethod.getMethodAnnotation(RequestMapping.class);
        if (classMapping == null || methodMapping == null) {
            return null;
        }

        String classPath = classMapping.value().length > 0 ? classMapping.value()[0] : "";
        String methodPath = methodMapping.value().length > 0 ? methodMapping.value()[0] : "";
        return classPath + methodPath;
    }

    /**
     * 构建OpenAPI实例（关联安全方案）
     */
    @Bean
    @ConditionalOnProperty(name = "swagger.enable", havingValue = "true", matchIfMissing = true)
    public OpenAPI customOpenAPI() {
        SecurityRequirement securityRequirement = new SecurityRequirement();
        securityRequirement.addList("bearerAuth");

        return new OpenAPI()
                .info(new io.swagger.v3.oas.models.info.Info()
                        .title("测试项目")
                        .description("测试项目接口文档")
                        .version("1.0")
                        .contact(new io.swagger.v3.oas.models.info.Contact()
                                .name("沙龙果")
                                .email("1478699371@qq.com")
                                .url(QueryWlanAddressUtil.getInt() + "/doc.html")
                        )
                )
                .addSecurityItem(securityRequirement);
    }
}